iT邦幫忙

2021 iThome 鐵人賽

DAY 23
0
自我挑戰組

Java SE系列 第 23

Day23:交給專業的來

  • 分享至 

  • xImage
  •  

我們來看看Executor介面的內容:

package java.util.concurrent;
public interface Executor(){
    void execute(Runnable command);
}

一開始看到這個Executor的時候真的超困惑的,為什麼要用這個介面?我定義好的Runnable就丟進Thread來start()就好了啊~何必再搞一個Executor把Runnable丟進去勒?

這就是一個很好的思考點,假若我們不用這個Executor,如果我們想開10個執行緒來跑相同的Runnable,那我們大概會弄個for迴圈來做:

for(int i = 0; i < 10; i++){
    new Thread(someTask).start();
}

抑或是想弄個執行緒池的概念(相當於資料庫的連線池),我只要使用10個Thread實例來跑可能100個任務,不要每個任務都開新的Thread來跑。這在沒有Executor出現以前,我們必須手動寫出這樣的程式,光想像應該也知道不是這麼好寫吧?肯定會有很多流程控制要搞。

而在Executor介面出現以後,它把Runnable任務和Thread實例的指派與操作之間隔了一層execute()的抽象方法出來,在這個execute方法中我們就可以定義Runnable任務和Thread實例的關係了!而官方Java API就提供了很多現成、覆寫(override)好execute()方法的類別讓我們直接使用!比如上一段提到的執行緒池,我們只要如下撰寫:

public class Something(){
    void doSomething(Executor executor){
        executor.execute(() -> {
            do some thing
        });
    }
}
public static void main(String[] args){
    Executor executorService = Executors.newFixedThreadPool(10);
    Something some = new Something();
    some.doSomething(executorService);
}

在我們真正要做任務的Something類別中我們用Executor的execute方法來定義要做的Runnable任務,而在Main方法要執行時,創建出我們需要的Execute服務(官方API提供了各種Execute服務,不是只有上面範例這個),並指派進Something類別中,程式執行時就會使用我們指派的Execute服務進行程式了!這邊我們採用的是newFixedThreadPool,可以指定需要創建的執行緒數量,程式實際就只會創建出指派數量的執行緒來重複利用。

這種隔一層的設計讓我想到過去做專題時用過的DAO介面,我們在Service中寫的都是定義為DAO介面型別的變數,而實際指派給變數的實例可以是連線池版本的DAO,或者是純JDBC版本輸入帳號密碼創建連線的DAO,但不管指派哪種實例給變數,都不會影響Service實作的程式碼!因為只要透過介面定義的方法及其方法簽章,就能預期輸入以及輸出的東西是什麼了。官方Java API也利用這樣隔一層的方式推出了Executor介面,程式中都可以先定義這個Executor,而實際要使用哪一種Executor實例就都可以再抽換。


上一篇
Day22:歐印萬
下一篇
Day24:老闆我等等來拿
系列文
Java SE30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言